#include <linux/input.h>
#include <linux/uinput.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
#include <string.h>
#include <stdint.h>
#include <stdio.h>

int reportkey(int fd, uint16_t type, uint16_t keycode, int32_t value)
{
    int ret;

    struct input_event ev;

    memset(&ev, 0, sizeof(struct input_event));

    ev.type = type;
    ev.code = keycode;
    ev.value = value;

    ret = write(fd, &ev, sizeof(struct input_event));
    if (ret < 0) {
        printf("report key error!\n");
        return ret;
    }

/*  printf("key is %d %d\n", keycode, value);*/

    return 0;
}

int main(void)
{
    int fd, ret;

    /* Open */
    fd = open("/dev/input/uinput", O_WRONLY | O_NONBLOCK);
    if (fd < 0) {
        return fd;
    }

    /* set UInput Type */
    ret = ioctl(fd, UI_SET_EVBIT, EV_KEY);
    ret = ioctl(fd, UI_SET_EVBIT, EV_SYN);

    /* set which key be used */
    ret = ioctl(fd, UI_SET_KEYBIT, KEY_D);

    /* configure UInput device information */
    struct uinput_user_dev uidev;
    memset(&uidev, 0, sizeof(struct uinput_user_dev));
    snprintf(uidev.name, UINPUT_MAX_NAME_SIZE, "uinput-sample");
    uidev.id.bustype = BUS_USB;
    uidev.id.vendor = 0x1234;
    uidev.id.product = 0xfedc;
    uidev.id.version = 1;
    ret = write(fd, &uidev, sizeof(struct uinput_user_dev));

    /* create the uinput device */
    ret = ioctl(fd, UI_DEV_CREATE);
    if (ret < 0) {
        close(fd);
        return ret;
    }

    int i = 100;
    while (--i) {
        reportkey(fd, EV_KEY, KEY_D, 1);
        reportkey(fd, EV_SYN, SYN_REPORT, 0);
        reportkey(fd, EV_KEY, KEY_D, 0);
        reportkey(fd, EV_SYN, SYN_REPORT, 0);
        sleep(1);
    }

    ioctl(fd, UI_DEV_DESTROY);

    close(fd);

    return 0;
}
